import * as THREE from 'three'
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls'
import Stats from 'three/examples/jsm/libs/stats.module.js'

import {MTLLoader}  from 'three/examples/jsm/loaders/MTLLoader'
import {OBJLoader}  from 'three/examples/jsm/loaders/OBJLoader'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';

import { MeshLine, MeshLineMaterial, MeshLineRaycast } from 'three.meshline';

export const space = () => {
  let cont = document.getElementById('cont')

  let scene=null
  ,camera=null
  ,renderer=null
  ,controls
  ,stats
  ,pointLight
  ,pointLight2
  ,pointLight3
  ,ambientLight
  ,gridHelper

  // Init scene 
  scene = new THREE.Scene()
  scene.background = new THREE.Color(0x222222)

  // Init Camera
  camera = new THREE.PerspectiveCamera(45, window.clientWidth / window.clientHeight, 1, 6000)
  camera.position.set(300,300, 0)

  // Init Light
  pointLight = new THREE.PointLight( 'yellow',2 )
  pointLight.position.set( 100, 30, 100 )
  pointLight.castShadow = true
  scene.add( pointLight )

  pointLight2 = new THREE.PointLight( 'blue',2 )
  pointLight2.position.set( -100, 30, -100 )
  pointLight2.castShadow = true
  scene.add( pointLight2 )

  pointLight3 = new THREE.PointLight( '#fff',2 )
  pointLight3.position.set( 300, 200, -300 )
  pointLight3.castShadow = true
  scene.add( pointLight3 )
  scene.add(new THREE.PointLightHelper(pointLight3,1))


  ambientLight = new THREE.AmbientLight('#fff',1) // obj 唯一 id
  scene.add(ambientLight)

  // 网格
  gridHelper = new THREE.GridHelper(400, 160, new THREE.Color(0x555555), new THREE.Color(0x333333))
  scene.add(gridHelper)

  /* let geometry = new THREE.BoxGeometry(1,1,1)
  let material = new THREE.MeshBasicMaterial({color: 0x00ff00})
  let mesh = new THREE.Mesh(geometry, material)
  scene.add(mesh) */

  // Init renderer
  renderer = new THREE.WebGLRenderer({antialias: true})
  renderer.shadowMap.enabled = true
  renderer.setPixelRatio(window.devicePixelRatio)
  renderer.setSize(window.innerWidth, window.innerHeight)
  cont.appendChild(renderer.domElement)

  // 鼠标键盘控制
  controls = new OrbitControls(camera, renderer.domElement)
  controls.enableDamping = true
  controls.dampingFactor = 0.25
  controls.screenSpacePanning = false
  // controls.maxDistance = 800
  controls.enableZoom = true;      //是否可以缩放
  // controls.autoRotate = true;   //是否自动旋转
  controls.autoRotateSpeed = 0.3;
  controls.minDistance = 1;        //设置相机距离原点的最远距离
  controls.maxDistance = 1000;     //设置相机距离原点的最远距离
  controls.update()


  // 性能监视器
  stats = new Stats()
  cont.appendChild(stats.domElement)


/* // 圆圈扫描
  const uniform = {
      u_color: { value: new THREE.Color("#5588aa") },
      u_tcolor: { value: new THREE.Color("red") },
      u_r: { value: 0.25 },
      u_length: { value: 20 }, //扫过区域
      u_max: { value: 100 } //扫过最大值
  };

  const Shader = {
      vertexShader: `
      varying vec3 vp;
      void main(){
        vp = position;
        gl_Position	= projectionMatrix * modelViewMatrix * vec4(position, 1.0);
      }
  `,
      fragmentShader: `
      varying vec3 vp;
      uniform vec3 u_color;
      uniform vec3 u_tcolor;
      uniform float u_r;
      uniform float u_length;
      uniform float u_max;
      float getRadius(float x, float y){
          return  sqrt((x-0.0)*(x-0.0)+(y-0.0)*(y-0.0)); //sqrt开根号 取R
      }
      void main(){
          float uOpacity = 0.3;
          vec3 vColor = u_color;
          float uLength = getRadius(vp.x,vp.z);
          if ( uLength <= u_r && uLength > u_r - u_length ) {
              float op = sin( (u_r - uLength) / u_length ) + 0.1;
              uOpacity = op;
              if( vp.y<0.0){
                  vColor = u_color * op;
              }else{
                  vColor = u_tcolor;
              };
          }

          gl_FragColor = vec4(vColor,uOpacity);
      }
  `
  }

  const material = new THREE.ShaderMaterial({
    vertexShader: Shader.vertexShader,
    fragmentShader: Shader.fragmentShader,
    side: THREE.DoubleSide,
    uniforms: uniform,
    transparent: true,
    depthWrite: false,
  }); 
*/

/* // 上下扫描

  const shader1 = [
  {   //高度一致
      vertexShader: [
          'varying vec3 vColor;',
          'varying vec3	vVertexNormal;',
          "varying vec2 vUv;",
          'varying float v_pz; ',
          'void main(){',
          "   vUv = uv;",
          '   v_pz = position.y; ',
          '	vVertexNormal	= normalize(normal);',
          '   vColor = color;',
          '	gl_Position	= projectionMatrix * modelViewMatrix * vec4(position, 1.0);',
          '}'
      ].join('\n'),
      fragmentShader: [
          'uniform float	boxH;',
          'varying vec3	vVertexNormal;',
          'varying vec3 vColor;',
          "varying vec2 vUv;",
          'varying float v_pz; ',
          'float plot (vec2 st, float pct){',
          'return  smoothstep( pct-8.0, pct, v_pz) -',
          'smoothstep( pct, pct+0.02, v_pz);',
          '}',
          'void main(){',
          'float f1 = plot(vUv,boxH);',
          'vec4 b1 = mix(vec4(1.0,1.0,1.0,1.0),vec4(f1,f1,f1,1.0),0.8);',
          'gl_FragColor = mix(vec4(vColor,1.0),b1,f1);',
          'gl_FragColor = vec4(gl_FragColor.r,gl_FragColor.g,gl_FragColor.b,0.9);',
          ' if(vVertexNormal.y > 0.5){gl_FragColor = vec4(vColor, 1.0);}',
          '}'
      ].join('\n'),
  },
  {   //高度不一致
      vertexShader: [
          'varying vec3 vColor;',
          'varying vec3	vVertexNormal;',
          "varying vec2 vUv;",
          'varying float v_px; ',
          'varying float v_py; ',
          'void main(){',
          "   vUv = uv;",
          '   v_py = (modelViewMatrix * vec4(position, 1.0)).y; ',
          '   v_px = (modelViewMatrix * vec4(position, 1.0)).x; ',
          '	vVertexNormal	= normalize(normal);',
          '   vColor = color;',
          '	gl_Position	= projectionMatrix * modelViewMatrix * vec4(position, 1.0);',
          '}'
      ].join('\n'),
      fragmentShader: [
          'uniform float	boxH;',
          'varying vec3	vVertexNormal;',
          'varying vec3 vColor;',
          "varying vec2 vUv;",
          'varying float v_px; ',
          'varying float v_py; ',
          'float plot (float st, float pct){',
          'return  smoothstep( pct-8.0, pct, st) -',
          'smoothstep( pct, pct+0.02, st);',
          '}',
          'void main(){',
          'float d = length(vec2(v_px,v_py));',
          // 'float f1 = plot(d,boxH);',
          'float f1 = plot(v_py,boxH);',
          'vec4 b1 = mix(vec4(1.0,1.0,1.0,1.0),vec4(f1,f1,f1,1.0),0.8);',
          'gl_FragColor = mix(vec4(vColor,1.0),b1,f1);',
          'gl_FragColor = vec4(gl_FragColor.r,gl_FragColor.g,gl_FragColor.b,0.9);',
          ' if(vVertexNormal.y > 0.5){gl_FragColor = vec4(vColor, 1.0);}',
          '}'
      ].join('\n')
  }
]

const  ShaderBar = {
  uniforms: {
      boxH: { value: -10.0 },
  },
  vertexShader: shader1[1].vertexShader,
  fragmentShader: shader1[1].fragmentShader
}
const material1 = new THREE.ShaderMaterial({
  uniforms: ShaderBar.uniforms,
  vertexShader: ShaderBar.vertexShader,
  fragmentShader: ShaderBar.fragmentShader,
  vertexColors: ShaderBar,
});
material1.needsUpdate = true  
*/

// 建筑白膜
/* new GLTFLoader().load( './modal/a.glb', function ( objects) {
    console.log(objects)
    let object=objects.scene
    object.traverse(child =>{
      child.material=material
    })
    scene.add( object)
    object.position.set(70, 0,0)
  })
new THREE.TextureLoader() */


  // 线框shader
  const lineMaterial = new THREE.LineBasicMaterial({
    // 线的颜色
    color: 'yellow',
    transparent: true,
    linewidth: 50,
    opacity: 1.0,
    //depthTest: true,
  });
  //解决z-flighting
  lineMaterial.polygonOffset = true; 
  ;
  lineMaterial.polygonOffsetUnits = 1.0;
  const uniform = {
    time: { value:0.01 }
  };
  //Phong材质
  const material6 =  new THREE.MeshPhongMaterial({
    color: 'yellow',
    transparent: true,
    side:THREE.DoubleSide,
    opacity: 0.3,
  });

  const Gradient = {
    vs:`
    varying vec2 vUv;
    void main()
    {
      vUv = uv;
      gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
    }
      `,
          fs:`
    uniform float time;
    varying vec2 vUv;
    void main( void ) {
        vec2 position = - 1.0 + 2.0 * vUv;
        float red = abs( sin( position.x * position.y + time / 5.0 ) );
        float green = abs( sin( position.x * position.y + time / 4.0 ) );
        float blue = abs( sin( position.x * position.y + time / 3.0 ) );
        gl_FragColor = vec4( red, green, blue, 1.0 );

    }
    `
  }

  
  const Gradient2 = {
    vs:`
    varying vec2 vUv;
    varying vec3 fNormal;
    varying vec3 vPosition;
    void main()
    {
        vUv = uv;
        fNormal=normal;
        vPosition=position;
        vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
        gl_Position = projectionMatrix * mvPosition;
    }
      `,
    fs:`
      uniform float time;
      varying vec2 vUv;
      uniform sampler2D colorTexture;
      uniform sampler2D colorTexture1;
      varying vec3 fNormal;
      varying vec3 vPosition;
      void main( void ) {
          vec2 position = vUv;
          vec3 tempNomal= normalize(fNormal);
          float power=step(0.95,abs(tempNomal.y));
          vec4 colorb=texture2D(colorTexture1,position.xy);
          vec4 colora = texture2D(colorTexture,vec2(vUv.x,fract(vUv.y-time))); 
          if(power>0.95){
              gl_FragColor =colorb;
          }else{
              gl_FragColor =colorb+colorb*colora;      
          }         
      }
    `
  }
  let uniforms2;
  let  material2;
  // 向上的流光
  // new THREE.TextureLoader().load( './static/lg.png',texture1 => {
  //   new THREE.TextureLoader().load( './static/lg3.png',texture2 => {
  //     uniforms2= {
  //       time:{value:0.01},
  //       colorTexture: {
  //         value: texture1
  //       },
  //       colorTexture1: {
  //         value: texture2
  //       },
  //     }
  //     material2 = new THREE.ShaderMaterial({
  //       uniforms: uniforms2,
  //       vertexShader: Gradient2.vs ,
  //       fragmentShader: Gradient2.fs,
  //       blending: THREE.AdditiveBlending,
  //       transparent:true,
  //       depthTest: false,
  //       side:THREE.DoubleSide,
  //       //polygonOffset:true
  //     });
  //     new OBJLoader().load( './modal/lvdu.obj', function ( objects) {
  //       console.log(objects)
  //       objects.traverse(child=>{
  //         if (child.isMesh) {
  //           child.rotateY(Math.PI/5); 
  //           child.material=material2
  //         }                 
  //       });
  //       scene.add(objects);       
  //       objects.scale.set(0.3,0.3,0.3)
  //       // object.position.set(70, 0,0)   
  //     })
    
  //   })
  // })


  // new THREE.TextureLoader().load( './static/redCircle2.png',texture => {
  //   let uniforms = {
  //        "time": { value: 1.0 },
  //        "texture": { value:  texture }
  //    }
  //    uniforms.texture.value.wrapS = uniforms.texture.value.wrapT = THREE.RepeatWrapping;
  //    const plane = new THREE.Mesh(new THREE.PlaneBufferGeometry(50,50),new THREE.ShaderMaterial({
  //        uniforms:uniforms,
  //        vertexShader: Gradient.vs,
  //        fragmentShader: Gradient.fs,
  //        side:THREE.DoubleSide
  //    }))
  //    plane.rotateY(Math.PI/2)
  //    plane.position.set(100,100,0)
  //    scene.add(plane)
  // })

  // new OBJLoader().load( './modal/yintai.obj', function ( objects) {
  //   console.log(objects)
  //   objects.traverse(child=>{
  //     if (child.isMesh) {
  //       child.rotateY(Math.PI/5); 
  //       child.material=material6
  //       scene.add(child);       
  //       child.scale.set(0.1,0.1,0.1)
  //       //建筑物线框模式
  //       let edges = new THREE.EdgesGeometry(child.geometry,1);
  //       let lineS= new THREE.LineSegments(edges, lineMaterial);
  //       lineS.rotateY(Math.PI/5);
  //       scene.add(lineS); 
  //       lineS.scale.set(0.1,0.1,0.1)
  //     }                 
  //   });
  //   // object.position.set(70, 0,0)   
  // })


  const Gradient3 = {
    vs:`varying vec2 vUv;
        void main(){
        vUv = uv;
        gl_Position = projectionMatrix*viewMatrix*modelMatrix*vec4( position, 1.0 );
    }`,
    fs:`uniform float time; 
      varying vec2 vUv;
      uniform sampler2D dtPyramidTexture;
      uniform vec3 uColor;
      void main() {
            vec2 st = vUv;
            vec4 colorImage = texture2D(dtPyramidTexture, vec2(vUv.x,fract(vUv.y-time)));
          //float alpha=mix(0.1,1.0,clamp((1.0-vUv.y) * uColor.a,0.0,1.0)) +(1.0-sign(vUv.y-time*0.001))*0.2*(1.0-colorImage.r);
          vec3 diffuse =(1.0-colorImage.a)*vec3(0.8,1.0,0.0)+colorImage.rgb*vec3(0.8,1.0,0);
          gl_FragColor = vec4(diffuse,0.7);
      }`
  }
  let uniforms3,renderObject,angle=0,height=1.0
  
new THREE.TextureLoader().load( './static/gradual_blue_01.png',texture => {
 uniforms3 = {
    dtPyramidTexture: {
        value: texture
    },
    time: {
        value: 0.0
    },
    uColor:{
        value:new THREE.Color("#5588aa")
    }
  };
  let  material = new THREE.ShaderMaterial({
    uniforms: uniforms3,
    vertexShader: Gradient3.vs ,
    fragmentShader: Gradient3.fs,
    side:THREE.DoubleSide,
    transparent:true
  });
    
  function getGeometry(geometryScale){
    let geometry = new THREE.CylinderBufferGeometry( 0,6.4,11,4,1,false,0,6.3);
    geometry.scale(geometryScale.x,geometryScale.y,geometryScale.z);
    geometry.computeBoundingSphere();
    // var material = new THREE.MeshBasicMaterial( {color: 0xffff00} );
    var cylinder = new THREE.Mesh( geometry, material );
    cylinder.rotateZ(Math.PI)
    scene.add(cylinder)
    cylinder.position.set(0, 50, 0);
    return cylinder;
  }
  renderObject=getGeometry(new THREE.Vector3(10,10,10))
});
 
var texture = new THREE.TextureLoader().load("./static/yanhua.png");
// 创建精灵材质对象SpriteMaterial
var spriteMaterial = new THREE.SpriteMaterial({
  color:0xff00ff,//设置精灵矩形区域颜色
  rotation:Math.PI/4,//旋转精灵对象45度，弧度值
  map: texture,//设置精灵纹理贴图
});
// 创建精灵模型对象，不需要几何体geometry参数
var sprite = new THREE.Sprite(spriteMaterial);
scene.add(sprite);
// 控制精灵大小，比如可视化中精灵大小表征数据大小
sprite.scale.set(100, 100, 1); //// 只需要设置x、y两个分量就可以
sprite.position.set(0, 100, 0); 

  function buildLine(){
    var lineMaterial = new THREE.LineBasicMaterial({
      // 线的颜色
      color: "#57d8ff",
      transparent: true,
      linewidth: 5,
      opacity: 1.0,
      //depthTest: true,
    });
    //解决z-flighting
    lineMaterial.polygonOffset = true;
    lineMaterial.depthTest = true;
    lineMaterial.polygonOffsetFactor = 1;
    lineMaterial.polygonOffsetUnits = 1.0;
  
    new OBJLoader().load( './modal/baida.obj', function ( object) {
      var linegroup = new THREE.Group();
      object.traverse(child =>{
        if (child.isMesh) {
          //建筑物线框模式
          let edges = new THREE.EdgesGeometry(child.geometry,1);
          edges.scale(0.1,0.1,0.1)
          let lineS= new THREE.LineSegments(edges, lineMaterial);
          lineS.rotateY(Math.PI/5);
          lineS.position.set(0,0,0)
          linegroup.add(lineS)
          // scene.add(lineS); 
        }
      })
      scene.add( linegroup );
    })
  }

/*   let textureLoader=new THREE.TextureLoader()
  let resolution = new THREE.Vector2( window.innerWidth, window.innerHeight )
  let linePos=[ [[-200,5,-100],[100,5,-90],[120,5,200]], [ [200,12,110],[-90,12,90], [-110,12,-180]]]
  let collider_lines=[]
  
  
  
  addRoad()
  function addRoad(){
    textureLoader.load( './static/red_line.png', function( texture ) {
      textureLoader.load( './static/green_line.png', function( texture2 ) {
        
        
        var meshLineMaterial1 =new MeshLineMaterial({
          color: 'red',
          map:texture,
          useMap: true,
          lineWidth: 10,
          resolution: resolution,
          dashArray: 0.8,  // 破折号之间的长度和间距。(0 -无破折号)
          dashRatio: 0.3, // 定义可见和不可见之间的比率(0 -更可见，1 -更不可见)。
          dashOffset: 0,
          transparent: true,
          sizeAttenuation: 1, //使线宽不变，不管距离(1个单位是屏幕上的1px)(0 -衰减，1 -不衰减)
          side: THREE.DoubleSide,
          depthTest: false,
          blending: THREE.AdditiveBlending,
        })
        var meshLineMaterial2 =new MeshLineMaterial({
          color:'green',
          map:texture2,
          useMap: true,
          lineWidth: 10,
          resolution: resolution,
          dashArray: 0.8,  // 破折号之间的长度和间距。(0 -无破折号)
          dashRatio: 0.3, // 定义可见和不可见之间的比率(0 -更可见，1 -更不可见)。
          dashOffset: 0,
          transparent: true,
          sizeAttenuation: 1, //使线宽不变，不管距离(1个单位是屏幕上的1px)(0 -衰减，1 -不衰减)
          side: THREE.DoubleSide,
          depthTest: false,
          blending: THREE.AdditiveBlending,
        })
       linePos.forEach((e,i) =>{
        let meshLine = new MeshLine()
          meshLine.setGeometry(getLineGeo(e))
            let line = new THREE.Mesh(meshLine.geometry, (i % 2 === 0 ? meshLineMaterial1:meshLineMaterial2) )
            scene.add(line)
            line.position.y = 0
            collider_lines.push(line)
            //头顶飞线
            // addFlyLine(texture,texture2)
            //添加中转站
            // addStander(texture,texture2)
        })
      })
    })
  }
  function getLineGeo(list){
    let l = []
    for(let i =0;i<list.length;i++){
        l.push( new THREE.Vector3(list[i][0],list[i][1],list[i][2]));
    }
    const cat = new THREE.CatmullRomCurve3(l) //曲线路径
    const points = cat.getPoints(50) //曲线分五十段，也就是取 101个点
    return new THREE.Geometry().setFromPoints(points)
  } */



  // return ''


  const clock = new THREE.Clock()
   // render
   render()
   function render(){
     renderer.render(scene, camera)
     controls.update(clock.getDelta())
     stats.update()

      if(uniforms3&&uniforms3.time){

        uniforms3.time.value=uniforms3.time.value+0.005;
      }
      if(renderObject){
        // renderObject.rotation.y+=0.05;
        angle=angle+0.05;
        Math.sin(angle)>0?height=1.0:height=-1.0;
        // renderObject.translateY(height);
      }
      // if (sprite) sprite.translateY(-height);

     uniform.time.value+=0.01
     if(uniforms2&&uniforms2.time){
       
       uniforms2.time.value+=0.01
     }
     /* uniform.u_r.value += clock.getDelta() * 1000;
     if (uniform.u_r.value >= 100) {
         uniform.u_r.value = 20
     } */

    //  ShaderBar.uniforms.boxH.value =  ShaderBar.uniforms.boxH.value + 0.1
    //     if( ShaderBar.uniforms.boxH.value > 30){
    //         ShaderBar.uniforms.boxH.value =  -10.0
    //     }
     requestAnimationFrame(render) 
   }
 
   // resize
   window.addEventListener('resize', onWindowResize, false)
   function onWindowResize() {
     if (scene) {
       camera.aspect = window.innerWidth / window.innerHeight
       camera.updateProjectionMatrix()
       renderer.setSize(window.innerWidth, window.innerHeight)
     }
   }
   onWindowResize()
 
}
